package com.healthcloud.controller;

import com.google.common.collect.Lists;
import com.healthcloud.dto.req.MpLoginDTO;
import com.healthcloud.entity.Patient;
import com.healthcloud.entity.PatientRecord.PatientInfoVo;
import com.healthcloud.entity.SysUserEntity;
import com.healthcloud.entity.SysUserRoleEntity;
import com.healthcloud.entity.TokenEntity;
import com.healthcloud.interceptor.AuthorizationInterceptor;
import com.healthcloud.service.*;
import com.healthcloud.service.hospital.SysUserOrganiService;
import com.healthcloud.utils.ApiRes;
import com.healthcloud.utils.Constant;
import com.healthcloud.utils.IdcardInfoExtractorUtil;
import com.healthcloud.utils.JwtUtil;
import io.swagger.annotations.Api;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.bean.WxJsapiSignature;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.util.RandomUtils;
import me.chanjar.weixin.common.util.crypto.SHA1;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @author wangdi
 * @since 2024/9/3
 */
@ApiIgnore
@Api(value = "公众号登录接口", description = "")
@RestController
@RequestMapping("/mp")
public class WeChatController {

    private static final Logger LOG = LoggerFactory.getLogger(WeChatController.class);

    @Resource
    private PatientService patientService;

    @Resource
    private SysUserService sysUserService;

    @Resource
    private SysUserOrganiService sysUserOrganiService;

    @Resource
    private TokenService tokenService;

    @Resource
    private WxMpService wxMpService;

    /**
     * 获取code
     *
     * @param returnUrl
     * @return
     */
    @GetMapping("/authorize")
    public String authorize(@RequestParam String returnUrl) {
        String url = "";
        String encode = null;
        try {
            encode = URLEncoder.encode(returnUrl, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        String redirectUrl = wxMpService.getOAuth2Service().buildAuthorizationUrl(url, WxConsts.OAuth2Scope.SNSAPI_BASE, encode);
        return "redirect:" + redirectUrl;
    }

    @GetMapping("/userInfo")
    public ApiRes userInfo(@RequestParam String code, @RequestParam String returnUrl, HttpServletRequest request) {
        WxOAuth2AccessToken accessToken = null;
        try {
            accessToken = wxMpService.getOAuth2Service().getAccessToken(code);
        } catch (WxErrorException e) {
            LOG.error("微信网页授权:{}", e);
            if (e.getMessage().contains("40163")) {
                return new ApiRes(true, 40163, null, null, 40163);
            } else {

                throw new RuntimeException(e);
            }
        }
        String openId = accessToken.getOpenId();
        return new ApiRes(openId);
    }

    @GetMapping("/getSignature")
    public ApiRes userInfo(@RequestParam String url, HttpServletRequest request) {
        try {
            String appUrl = URLDecoder.decode(url, "UTF-8");
            long timestamp = System.currentTimeMillis() / 1000;
            String randomStr = RandomUtils.getRandomStr();
            String jsapiTicket = wxMpService.getJsapiTicket(false);
            String signature = SHA1.genWithAmple("jsapi_ticket=" + jsapiTicket,
                    "noncestr=" + randomStr, "timestamp=" + timestamp, "url=" + appUrl);
            com.healthcloud.dto.WxJsapiSignature wxJsapiSignature = new com.healthcloud.dto.WxJsapiSignature();
            wxJsapiSignature.setAppId(Constant.WX_APPID);
            wxJsapiSignature.setTimestamp(timestamp);
            wxJsapiSignature.setNonceStr(randomStr);
            wxJsapiSignature.setUrl(appUrl);
            wxJsapiSignature.setSignature(signature);
//            wxJsapiSignature.setJsapiTicket(jsapiTicket);
//            wxMpService.checkSignature(jsapiSignature.getTimestamp() + "", jsapiSignature.getNonceStr(), jsapiSignature.getSignature());
            return ApiRes.success(wxJsapiSignature);
        } catch (WxErrorException e) {
            LOG.error("", e);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
        return ApiRes.failure();
    }


    @RequestMapping("/autoLogin")
    public ApiRes autoLogin(@RequestBody MpLoginDTO mpLoginDTO) {

        String openId = mpLoginDTO.getOpenId();
        SysUserEntity sysUser = sysUserService.getByOpenId(openId);

        String token = null;
        if (Objects.nonNull(sysUser)) {
            Patient patient = patientService.findByUserId(sysUser.getId().intValue());
            token = JwtUtil.doGenerateToken(sysUser, patient.getIdCard());
        }

        return new ApiRes(token);
    }

    @Resource
    private UserService userService;
    @Resource
    private SysUserRoleService sysUserRoleService;
    @RequestMapping("/login")
    public ApiRes mpLogin(@RequestBody MpLoginDTO mpLoginDTO) {
        SysUserEntity sysUser = sysUserService.getByOpenId(mpLoginDTO.getOpenId());
        if (Objects.isNull(sysUser)) {
            sysUser = sysUserService.queryByUserName(mpLoginDTO.getPhone());
        }

        if (Objects.isNull(sysUser)) {
            sysUser = new SysUserEntity();
            sysUser.setMobile(mpLoginDTO.getPhone());
            sysUser.setUsername(mpLoginDTO.getPhone());
            sysUser.setRealName(mpLoginDTO.getName());
            sysUser.setStatus(1);
            sysUser.setUserKind("1");
            sysUser.setPassword(Constant.DEFAULT_PWD);
            if (StringUtils.isNotBlank(mpLoginDTO.getOpenId())) {
                sysUser.setWxOpenId(mpLoginDTO.getOpenId());
            }
            sysUserService.save(sysUser);
            sysUserRoleService.saveOrUpdate(sysUser.getId(), Lists.newArrayList(16L));

//            sysUserOrganiService.add(sysUser.getId(), orgId);
        } else {
            if (StringUtils.isNotBlank(mpLoginDTO.getOpenId())) {
                sysUser.setWxOpenId(mpLoginDTO.getOpenId());
                sysUser.setRealName(mpLoginDTO.getName());
            }
            sysUserService.update(sysUser);
        }
        Patient patient = patientService.findByUserId(sysUser.getId().intValue());
        if (Objects.nonNull(patient)) {
            if (!Objects.equals(patient.getIdCard(), mpLoginDTO.getIdCard())) {
                return ApiRes.failure("已经绑定过病人，请输入原绑定病人手机号");
            }
        }

        if (Objects.isNull(patient)) {
            // 不存在，需要绑定
            patient = new Patient();
            patient.setIdCard(mpLoginDTO.getIdCard());
            try {
                IdcardInfoExtractorUtil id = new IdcardInfoExtractorUtil(mpLoginDTO.getIdCard());
                String sex = id.getGender();
                SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");

                patient.setAge(id.getAge() + "");
                patient.setBirthday(id.getBirthday());
                patient.setGender(Integer.parseInt(sex));
            } catch (NumberFormatException e) {
                throw new RuntimeException(e);
            }
            patient.setUserId(sysUser.getId().intValue());
            patient.setRealname(mpLoginDTO.getName());
            patient.setPhone(mpLoginDTO.getPhone());
            if (Objects.nonNull(mpLoginDTO.getOrgId())) {
                patient.setHospitalId(mpLoginDTO.getOrgId().intValue());
            }
            patientService.saveOrUpdate(patient);
        }

        // todo  token
        String token = JwtUtil.doGenerateToken(sysUser, mpLoginDTO.getIdCard());
        return new ApiRes(token);
    }


    @GetMapping("/getInfo")
    public ApiRes getInfo(HttpServletRequest request) throws WxErrorException {
        String token = JwtUtil.getTokenFromRequest(request);
        LOG.info("token:{}", token);
        Long userId = JwtUtil.getUserIdFromRequest(request);
        SysUserEntity sysUser = sysUserService.queryObjectByid(userId);

        Patient patient = patientService.findByUserId(userId.intValue());
        Map<String, String> map = new HashMap<>();
        if (Objects.nonNull(patient)) {
            map.put("idCard", patient.getIdCard());
        }

        if (Objects.nonNull(sysUser)) {
            map.put("name", sysUser.getRealName());
        }
        return new ApiRes(map);
    }

}
